<?php
/**
 * Created by PhpStorm.
 * User: 我想有个家
 * Date: 2019/4/23
 * Time: 0:13
 */

namespace App\Controller\admin\admin;


use App\Controller\Base;
use App\Lib\Redis;
use App\Model\AuAdminRole;
use App\Model\AuRole;
use App\Model\AuRoleRule;
use App\Model\AuRule;
use App\Lib\Tree;
use Hyperf\DbConnection\Db;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\RequestMapping;

/**
 * Class Role
 * @Controller(prefix="a/role")
 * @Middleware(\App\Middleware\AdminMiddleware::class)
 */
class RoleController extends Base {
    /**
     * 查询角色列表
     * @RequestMapping(path="lists",methods="get")
     */
    public function getLists() {
        $status = $this->get('status');
        $condition = [];
        if ($status == 'no') {
            $condition['status'] = 0;
        } elseif ($status == 'yes') {
            $condition['status'] = 1;
        }
        $lists = AuRole::query()
            ->where($condition)
            ->select('id', 'name', 'description', 'status')
            ->get();
        return success(['lists' => $lists]);
    }

    /**
     * 添加/编辑角色
     * @return array
     * @RequestMapping(path="save",methods="post")
     */
    public function postSave() {
        $name = $this->body('name');
        $bewrite = $this->body('bewrite');
        $id = $this->body('id');
        if (empty($name) || empty($bewrite)) {
            return error('参数错误');
        }
        $data = [
            'name' => $name,
            'description' => $bewrite,
        ];
        if ($id) {
            $r = AuRole::query()->where('id', $id)->update($data);
        } else {
            $r = AuRole::query()->insert($data);
        }
        return $r ? success() : error();
    }

    /**
     * 查询单个信息
     * @return array
     * @RequestMapping(path="info",methods="get")
     */
    // public function getInfo() {
    //     $id = $this->get('id');
    //     $info = AuRole::query()
    //         ->where('id', $id)
    //         ->select('id', 'name', 'description', 'status')
    //         ->first();
    //     return $info ? success() : error('数据不存在');
    // }

    /**
     * 删除角色
     * @RequestMapping(path="del",methods="post")
     */
    public function postDel() {
        $id = $this->body('id');
        // 查询角色
        $data = AuRole::query()->where('id', $id)->count();
        if (empty($data)) {
            return error('要删除的角色不存在');
        }
        Db::beginTransaction();
        try {
            // 删除角色
            $res = AuRole::query()->where('id', $id)->delete();
            if ($res === false) {
                throw new \Exception('删除失败');
            }
            // 删除角色权限
            $res = AuRoleRule::query()->where('role_id', $id)->delete();
            if ($res === false) {
                throw new \Exception('删除失败');
            }
            // 删除用户角色
            $res = AuAdminRole::query()->where('role_id', $id)->delete();
            if ($res === false) {
                throw new \Exception('删除失败');
            }
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            return error($e->getMessage());
        }
        return success();
    }

    /**
     * 更改状态
     * @return array
     * @RequestMapping(path="status",methods="post")
     */
    public function postStatus() {
        $status = $this->body('status');
        $id = $this->body('id');
        if ($status) {
            $data = ['status' => 1];
        } else {
            $data = ['status' => 0];
        }
        $r = AuRole::query()
            ->where('id', $id)
            ->update($data);
        if ($r) {
            return success();
        } else {
            return error();
        }
    }

    /**
     * 获取菜单
     * @return array
     * @RequestMapping(path="rule",methods="get")
     */
    public function getRule() {
        $id = $this->get('id');
        $lists = AuRule::query()
            ->where('parent_id', '>', 0)
            ->select('id', 'name as label', 'type', 'parent_id')
            ->get()->toArray();
        foreach ($lists as &$list) {
            $list['value'] = $list['id'];
            if ($list['type'] == 1) {
                $list['parent_id'] = 0;
            }
            unset($list['type']);
        }
        if ($lists) {
            $lists = Tree::makeTree($lists);
            // 判断是否拥有权限
            $permission = $this->getPermission($id);
            foreach ($lists as &$list) {
                $list['has'] = [];
                foreach ($list['children'] as &$child) {
                    unset($child['parent_id']);
                    if (in_array($child['id'], $permission)) {
                        array_push($list['has'], $child['id']);
                    }
                }
                unset($list['parent_id']);
            }
        }
        return success(['lists' => $lists]);
    }


    /**
     * 查询权限
     * @param $id
     * @return array
     */
    private function getPermission($id) {
        return AuRoleRule::query()->where('role_id', $id)->pluck('permission_id')->toArray();
    }

    /**
     * 更新权限
     * @return array
     * @RequestMapping(path="rule",methods="post")
     */
    public function postRule() {
        $id = $this->body('id');
        $rule = $this->body('rule');
        if (empty($id)) {
            return error('非法参数');
        }
        $has = AuRole::query()->where('id', $id)->count();
        if ($has == 0) {
            return error('角色不存在');
        }
        $rule = explode(',', $rule);
        AuRoleRule::query()->where('role_id', $id)->delete();
        if ($rule) {
            // 检验权限
            $rule = AuRule::query()
                ->where('type', '=', 2)
                ->whereIn('id', $rule)
                ->pluck('id')
                ->toArray();
            if (empty($rule)) {
                return error('功能选择错误');
            }
            $rolePermission = [];
            foreach ($rule as $v) {
                $rolePermission [] = ['role_id' => $id, 'permission_id' => $v];
            }
            AuRoleRule::query()->insert($rolePermission);
        }
        return success();
    }

    /**
     * 刷新角色缓存
     */
    private function roleCache() {
        // 查询所有权限
        $rules = AuRoleRule::query()
            ->from('au_role_rule as rr')
            ->leftJoin('au_role as r', 'rr.role_id', '=', 'r.id')
            ->leftJoin('au_rule as p', 'rr.permission_id', '=', 'p.id')
            ->where('status', 1)
            ->where('type', 2)
            ->select('r.id', 'permission_id', 'ext')
            ->get()->toArray();
        $data = [];
        foreach ($rules as $rule) {
            !isset($data[$rule['id']]) && $data[$rule['id']] = ['menus' => []];
            $data[$rule['id']]['menus'][] = $rule['permission_id'];
            $ext = explode("\n", $rule['ext']);
            foreach ($ext as $v) {
                $data[$rule['id']][$v] = 1;
            }
        }
        $redis = Redis::get();
        foreach ($data as $k => $v) {
            $v['menus'] = implode(',', $v['menus']);
            $redis->hMSet("ar:{$k}", $v);
        }
    }

    /**
     * 刷新菜单缓存
     */
    private function ruleCache() {
        $all = AuRule::query()
            ->orderBy('sequence ', 'desc')
            ->orderBy('id')
            ->select('id,parent_id,name,path,ext')
            ->get()->toArray();
        $all = Tree::makeTree($all);
        foreach ($all as &$lv1) {
            unset($lv1['parent_id']);
            foreach ($lv1['children'] as &$lv2) {
                unset($lv2['parent_id']);
                $lv2['auth'] = [];
                foreach ($lv2['children'] as $lv3) {
                    $lv2['auth'][$lv3['id']] = $lv3['path'];
                }
                unset($lv2['children']);
            }
        }
        Redis::get()->set("admin_menus", md_json($all));
    }

    /**
     * 刷新所有缓存
     * @RequestMapping(path="refresh",methods="get")
     */
    public function getRefresh() {
        if ($this->request->_admin['id'] != 1) {
            return error('无访问权限', 10006);
        }
        $this->ruleCache();
        $this->roleCache();
        return success();
    }
}
